using System;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.XPath;
using System.Collections;

namespace SCS.Web.Controls
{
	/// <summary>
	/// Summary description for MultiMenuItem.
	/// </summary>
	public class MultiMenuItem
	{
		#region Fields
		private MultiMenuGroup subMenuGroup = null;
		private MultiMenuGroup parentMenuGroup = null;
		private string id = string.Empty;
		private string tag = string.Empty;
		private string url = string.Empty;
		private string cssClass = string.Empty;
		private string cssClassOver = string.Empty;
		private string cssClassSelected = string.Empty;
		private string cssClassSelectedOver = string.Empty;
		private string cssClassDisabled = string.Empty;
		private string text = string.Empty;
		private string toolTip = string.Empty;
		private string leftIcon = string.Empty;
		private string leftIconOver = string.Empty;
		private string leftIconSelected = string.Empty;
		private string leftIconSelectedOver = string.Empty;
		private string leftIconDisabled = string.Empty;
		private string leftIconAltText = string.Empty;
		private string rightIcon = string.Empty;
		private string rightIconOver = string.Empty;
		private string rightIconSelected = string.Empty;
		private string rightIconSelectedOver = string.Empty;
		private string rightIconDisabled = string.Empty;
		private string rightIconAltText = string.Empty;	
		private string image = string.Empty;
		private string imageOver = string.Empty;
		private string imageSelected = string.Empty;
		private string imageSelectedOver = string.Empty;
		private string imageAltText = string.Empty;
		private string onClickClientCode = string.Empty;        
		private AccessKeyType accessKey = AccessKeyType.None;
		private AccessKeyModifierType accessKeyModifier = AccessKeyModifierType.Alt;
		private int width = -1;
		private int height = -1;
		private int leftIconWidth = -1;
		private int leftIconHeight = -1;
		private int rightIconWidth = -1;
		private int rightIconHeight = -1;
		private int imageHeight = -1;
		private int imageWidth = -1;
		private int tabIndex = -1;
		private bool isDivider = false;
		private bool postBack = true;
		private bool selected = false;
		private bool enabled = true;
		private bool visible = true;
		#endregion

		#region Serialization Mappings

		string[,] serializationMap = new  string[,] {	{"MultiMenu", "MI"}, 
														{"IsDivider", "D"},
														{"Width", "W"},
														{"Height", "H"}, 
														{"Text", "T"}, 
														{"ToolTip", "TT"}, 
														{"Url", "U"},
														{"AccessKey", "A"},
														{"AccessKeyModifier", "AM"},
														{"PostBack", "P"},
														{"CssClass", "C"},
														{"CssClassOver", "CO"},
														{"CssClassSelected", "CS"},
														{"CssClassSelected", "CSO"},
														{"CssClassDisabled", "CD"},
														{"Image", "I"},
														{"ImageOver", "IO"},
														{"ImageSelected", "IS"},
														{"ImageSelectedOver", "ISO"},
														{"ImageAltText", "IA"},
														{"ImageWidth", "IW"},
														{"ImageHeight", "IH"},
														{"LeftIcon", "LI"},
														{"LeftIconOver", "LIO"},
														{"LeftIconSelected", "LIS"},
														{"LeftIconSelectedOver", "LISO"},
														{"LeftIconDisabled", "LID"},
														{"LeftIconAltText", "LIA"},
														{"LeftIconWidth", "LIW"},
														{"LeftIconHeight", "LIH"},
														{"RightIcon", "RI"},
														{"RightIconOver", "LIO"},
														{"RightIconSelected", "LIS"},
														{"RightIconSelectedOver", "LISO"},
														{"RightIconDisabled", "LID"},
														{"RightIconAltText", "RIA"},														
														{"RightIconWidth", "RIW"},
														{"RightIconHeight", "RIH"},
														{"Tag", "TG"},
														{"Selected", "S"},
														{"Enabled", "E"},
														{"Visible", "V"},
														{"OnClickClientCode", "CC"}
														
													};
		#endregion

		#region Constructors
		public MultiMenuItem()
		{
		}
		
		public MultiMenuItem(string text)
		{
			this.Text = text;
		}

		public MultiMenuItem(string text, string url)
		{
			this.Text = text;
			this.Url = url;
		}

		public MultiMenuItem(string text, string url, string image)
		{
			this.Text = text;
			this.Url = url;
			this.Image = image;
		}

		public MultiMenuItem(string text, string url, string image, string tag)
		{
			this.Text = text;
			this.Url = url;
			this.Image = image;
			this.Tag = tag;
		}
		#endregion

		private string getNodeText(string shortName, bool compress)
		{
			if (compress)
				return shortName;

			for (int i = 0; i < this.serializationMap.GetLength(0); i++)
			{
				if (this.serializationMap[i, 1].Equals(shortName))
					return this.serializationMap[i, 0];
			}
			return shortName;
		}
		
		internal void Serialize(XmlTextWriter writer, bool compress)
		{			
			writer.WriteStartElement(this.getNodeText("MI", compress));			

			if (this.Tag.Length > 0)
				writer.WriteAttributeString(this.getNodeText("TG", compress), this.Tag);

			if (this.IsDivider)
				writer.WriteAttributeString(this.getNodeText("D", compress), this.IsDivider.ToString());

			if (this.Width > -1)
				writer.WriteAttributeString(this.getNodeText("W", compress), this.Width.ToString());

			if (this.Height > -1)
				writer.WriteAttributeString(this.getNodeText("H", compress), this.Height.ToString());

			if (this.Text.Length > 0)
				writer.WriteAttributeString(this.getNodeText("T", compress), this.Text.Replace("\"", "&quot;"));

			if (this.ToolTip.Length > 0)
				writer.WriteAttributeString(this.getNodeText("TT", compress), this.ToolTip.Replace("\"", "&quot;"));

			if (this.Url.Length > 0)
				writer.WriteAttributeString(this.getNodeText("U", compress), this.Url.Replace("&", "&amp;"));

			if (this.AccessKey != AccessKeyType.None)
				writer.WriteAttributeString(this.getNodeText("A", compress), Enum.GetName(typeof(AccessKeyType), this.AccessKey));

			if (this.AccessKeyModifier != AccessKeyModifierType.Alt)
				writer.WriteAttributeString(this.getNodeText("AM", compress), Enum.GetName(typeof(AccessKeyModifierType), this.AccessKeyModifier));

			if (! this.PostBack)
				writer.WriteAttributeString(this.getNodeText("P", compress), this.PostBack.ToString());

			if (this.CssClass.Length > 0)
				writer.WriteAttributeString(this.getNodeText("C", compress), this.CssClass);

			if (this.CssClassOver.Length > 0)
				writer.WriteAttributeString(this.getNodeText("CO", compress), this.CssClassOver);

			if (this.CssClassSelected.Length > 0)
				writer.WriteAttributeString(this.getNodeText("CS", compress), this.CssClassSelected);

			if (this.CssClassSelectedOver.Length > 0)
				writer.WriteAttributeString(this.getNodeText("CSO", compress), this.CssClassSelectedOver);

			if (this.Image.Length > 0)
				writer.WriteAttributeString(this.getNodeText("I", compress), this.Image);
			
			if (this.ImageWidth > -1)
				writer.WriteAttributeString(this.getNodeText("IW", compress), this.ImageWidth.ToString());

			if (this.ImageHeight > -1)
				writer.WriteAttributeString(this.getNodeText("IH", compress), this.ImageHeight.ToString());

			if (this.ImageAltText.Length > 0)
				writer.WriteAttributeString(this.getNodeText("IA", compress), this.ImageAltText);

			if (this.ImageOver.Length > 0)
				writer.WriteAttributeString(this.getNodeText("IO", compress), this.ImageOver);

			if (this.ImageSelected.Length > 0)
				writer.WriteAttributeString(this.getNodeText("IS", compress), this.ImageSelected);

			if (this.ImageSelectedOver.Length > 0)
				writer.WriteAttributeString(this.getNodeText("ISO", compress), this.ImageSelectedOver);

			if (this.LeftIcon.Length > 0)
				writer.WriteAttributeString(this.getNodeText("LI", compress), this.LeftIcon);

			if (this.LeftIconOver.Length > 0)
				writer.WriteAttributeString(this.getNodeText("LIO", compress), this.LeftIconOver);

			if (this.LeftIconSelected.Length > 0)
				writer.WriteAttributeString(this.getNodeText("LIS", compress), this.LeftIconSelected);
			
			if (this.LeftIconSelectedOver.Length > 0)
				writer.WriteAttributeString(this.getNodeText("LISO", compress), this.LeftIconSelectedOver);

			if (this.LeftIconDisabled.Length > 0)
				writer.WriteAttributeString(this.getNodeText("LID", compress), this.LeftIconDisabled);
		
			if (this.LeftIconAltText.Length > 0)
				writer.WriteAttributeString(this.getNodeText("LIA", compress), this.LeftIconAltText);

			if (this.RightIcon.Length > 0)
				writer.WriteAttributeString(this.getNodeText("RI", compress), this.RightIcon);

			if (this.RightIconOver.Length > 0)
				writer.WriteAttributeString(this.getNodeText("RIO", compress), this.RightIconOver);

			if (this.RightIconSelected.Length > 0)
				writer.WriteAttributeString(this.getNodeText("RIS", compress), this.RightIconSelected);
			
			if (this.RightIconSelectedOver.Length > 0)
				writer.WriteAttributeString(this.getNodeText("RISO", compress), this.RightIconSelectedOver);

			if (this.RightIconDisabled.Length > 0)
				writer.WriteAttributeString(this.getNodeText("RID", compress), this.RightIconDisabled);
		
			if (this.RightIconAltText.Length > 0)
				writer.WriteAttributeString(this.getNodeText("RIA", compress), this.RightIconAltText);

			if (this.RightIconWidth > -1)
				writer.WriteAttributeString(this.getNodeText("RIW", compress), this.RightIconWidth.ToString());

			if (this.RightIconHeight  > -1)
				writer.WriteAttributeString(this.getNodeText("RIH", compress), this.RightIconHeight.ToString());

			if (this.LeftIconWidth > -1)
				writer.WriteAttributeString(this.getNodeText("LIW", compress), this.LeftIconWidth.ToString());

			if (this.LeftIconHeight > -1)
				writer.WriteAttributeString(this.getNodeText("LIH", compress), this.LeftIconHeight.ToString());

			if (this.Selected)
				writer.WriteAttributeString(this.getNodeText("S", compress), this.Selected.ToString());

			if (!this.Enabled)
				writer.WriteAttributeString(this.getNodeText("E", compress), this.Enabled.ToString());

			if (!this.visible)
				writer.WriteAttributeString(this.getNodeText("V", compress), this.Visible.ToString());

			if (this.onClickClientCode.Length > 0)
				writer.WriteAttributeString(this.getNodeText("CC", compress), this.OnClickClientCode);

		}
		internal void DeserializeMenuItem(MultiMenuItem menuItem, XPathNavigator navigator, bool isCompressed)
		{
			navigator.MoveToFirstAttribute();
			this.setProperty(menuItem, navigator, isCompressed);

			while (navigator.MoveToNextAttribute())
				this.setProperty(menuItem, navigator, isCompressed);
		}
		
		private void setProperty(MultiMenuItem menuItem, XPathNavigator navigator, bool isCompressed)
		{
			try
			{
				if (navigator.Name.Equals(this.getNodeText("TG", isCompressed)))
					menuItem.Tag = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("W", isCompressed)))
					menuItem.Width = int.Parse(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("H", isCompressed)))
					menuItem.Height = int.Parse(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("D", isCompressed)))
					menuItem.IsDivider = bool.Parse(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("T", isCompressed)))
					menuItem.Text = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("TT", isCompressed)))
					menuItem.ToolTip = navigator.Value;
				
				else if (navigator.Name.Equals(this.getNodeText("U", isCompressed)))
					menuItem.Url = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("A", isCompressed)))
					menuItem.AccessKey = (AccessKeyType)Enum.Parse(typeof(AccessKeyType), navigator.Value, true);

				else if (navigator.Name.Equals(this.getNodeText("AM", isCompressed)))
					menuItem.AccessKeyModifier = (AccessKeyModifierType)Enum.Parse(typeof(AccessKeyModifierType), navigator.Value, true);
				
				else if (navigator.Name.Equals(this.getNodeText("P", isCompressed)))
					menuItem.PostBack = this.ParseFlag(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("C", isCompressed)))
					menuItem.CssClass = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("CO", isCompressed)))
					menuItem.CssClassOver = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("CS", isCompressed)))
					menuItem.CssClassSelected = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("CSO", isCompressed)))
					menuItem.CssClassSelectedOver = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("I", isCompressed)))
					menuItem.Image = navigator.Value;
				
				else if (navigator.Name.Equals(this.getNodeText("IA", isCompressed)))
					menuItem.ImageAltText = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("IO", isCompressed)))
					menuItem.ImageOver = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("IS", isCompressed)))
					menuItem.ImageOver = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("ISO", isCompressed)))
					menuItem.ImageSelectedOver = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("LI", isCompressed)))
					menuItem.LeftIcon = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("LIA", isCompressed)))
					menuItem.LeftIconAltText = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("RI", isCompressed)))
					menuItem.RightIcon = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("RIA", isCompressed)))
					menuItem.RightIconAltText = navigator.Value;

				else if (navigator.Name.Equals(this.getNodeText("IH", isCompressed)))
					menuItem.ImageHeight = int.Parse(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("IW", isCompressed)))
					menuItem.ImageWidth = int.Parse(navigator.Value);
				
				else if (navigator.Name.Equals(this.getNodeText("LIH", isCompressed)))
					menuItem.LeftIconHeight = int.Parse(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("LIW", isCompressed)))
					menuItem.LeftIconWidth = int.Parse(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("RIH", isCompressed)))
					menuItem.RightIconHeight = int.Parse(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("RIW", isCompressed)))
					menuItem.RightIconWidth = int.Parse(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("S", isCompressed)))
					menuItem.Selected = this.ParseFlag(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("E", isCompressed)))
					menuItem.Enabled = this.ParseFlag(navigator.Value);

				else if (navigator.Name.Equals(this.getNodeText("V", isCompressed)))
					menuItem.visible = this.ParseFlag(navigator.Value);
				
				else if (navigator.Name.Equals(this.getNodeText("CC", isCompressed)))
					menuItem.onClickClientCode = navigator.Value;
			}
			catch (Exception e)
			{
				string message = string.Format("Unable to set {0} to \"{1}\" due to type mismatch.", navigator.Name, navigator.Value);
				throw new ApplicationException(message, e);
			}
		}

		public MultiMenuGroup CreateMenuGroup()
		{
			this.SubMenuGroup = new MultiMenuGroup();
			this.SubMenuGroup.ParentMenuItem = this;
			return this.SubMenuGroup;
		}
		public MultiMenuGroup CreateMenuGroup(ExpandDirectionType expandDirection)
		{
			this.SubMenuGroup = new MultiMenuGroup();
			this.SubMenuGroup = new MultiMenuGroup(expandDirection);
			this.SubMenuGroup.ParentMenuItem = this;
			return this.SubMenuGroup;
		}
		public MultiMenuGroup CreateMenuGroup(ExpandDirectionType expandDirection, int width)
		{
			this.SubMenuGroup = new MultiMenuGroup();
			this.SubMenuGroup = new MultiMenuGroup(expandDirection, width);
			this.SubMenuGroup.ParentMenuItem = this;
			return this.SubMenuGroup;
		}
		public MultiMenuGroup CreateMenuGroup(ExpandDirectionType expandDirection, int width, int horizontalOffset, int verticalOffset)
		{
			this.SubMenuGroup = new MultiMenuGroup();
			this.SubMenuGroup = new MultiMenuGroup(expandDirection, width, horizontalOffset, verticalOffset);
			this.SubMenuGroup.ParentMenuItem = this;
			return this.SubMenuGroup;
		}
        		
		private bool ParseFlag(string s)
		{
			if (s.Length > 1)
				return bool.Parse(s);
			else
				return bool.Parse(s.Replace("0", "false").Replace("1", "true"));
		}		
	
		#region Properties

		public MultiMenuGroup SubMenuGroup
		{
			get { return this.subMenuGroup; }
			set { this.subMenuGroup = value; }
		}
		internal MultiMenuGroup ParentMenuGroup
		{
			get { return this.parentMenuGroup; }
			set { this.parentMenuGroup = value; }
		}
		internal int TabIndex
		{
			get { return this.tabIndex; }
			set { this.tabIndex = value; }
		}
		internal string ID_internal
		{
			get { return this.id; }
			set { this.id = value; } 
		}		
		public string Id
		{
			get { return this.id; }
		}
		public string Tag
		{
			get { return this.tag; }
			set { this.tag = value; }
		}
		public string Url
		{
			get { return this.url; }
			set { this.url = value; }
		}
		public AccessKeyType AccessKey
		{
			get { return this.accessKey; }
			set { this.accessKey = value; }
		}
		public AccessKeyModifierType AccessKeyModifier
		{
			get { return this.accessKeyModifier; }
			set { this.accessKeyModifier = value; }
		}
		public bool PostBack
		{
			get { return this.postBack; }
			set { this.postBack = value; }
		}
		public string CssClass
		{
			get { return this.cssClass; }
			set { this.cssClass = value; }
		}
		public string CssClassOver
		{
			get { return this.cssClassOver; }
			set { this.cssClassOver = value; }
		}
		public string CssClassSelected
		{
			get { return this.cssClassSelected; }
			set { this.cssClassSelected = value; }
		}
		public string CssClassSelectedOver
		{
			get { return this.cssClassSelectedOver; }
			set { this.cssClassSelectedOver = value; }
		}
		public string CssClassDisabled
		{
			get { return this.cssClassDisabled; }
			set { this.cssClassDisabled = value; }
		}
		public string Text
		{
			get { return this.text; }
			set { this.text = value; }
		}
		public string ToolTip
		{
			get { return this.toolTip; }
			set { this.toolTip = value; }
		}
		public string LeftIcon
		{
			get { return this.leftIcon; }
			set { this.leftIcon = value; }
		}
		public string RightIcon
		{
			get { return this.rightIcon; }
			set { this.rightIcon = value; }
		}
		public string LeftIconOver
		{
			get { return this.leftIconOver; }
			set { this.leftIconOver = value; }
		}
		public string LeftIconSelected
		{
			get { return this.leftIconSelected; }
			set { this.leftIconSelected = value; }
		}
        public string LeftIconSelectedOver
		{
			get { return this.leftIconSelectedOver; }
			set { this.leftIconSelectedOver = value; }
		}
		public string LeftIconDisabled
		{
			get { return this.leftIconDisabled; }
			set { this.leftIconDisabled = value; }
		}
		public string RightIconOver
		{
			get { return this.rightIconOver; }
			set { this.rightIconOver = value; }
		}
		public string RightIconSelected
		{
			get { return this.rightIconSelected; }
			set { this.rightIconSelected = value; }
		}
		public string RightIconSelectedOver
		{
			get { return this.rightIconSelectedOver; }
			set { this.rightIconSelectedOver = value; }
		}
		public string RightIconDisabled
		{
			get { return this.rightIconDisabled; }
			set { this.rightIconDisabled = value; }
		}
		public string Image
		{
			get { return this.image; }
			set { this.image = value; }
		}
		public string ImageAltText
		{
			get { return this.imageAltText; }
			set { this.imageAltText = value; }
		}
		public string ImageOver
		{
			get { return this.imageOver; }
			set { this.imageOver = value; }
		}
		public string ImageSelected
		{
			get { return this.imageSelected; }
			set { this.imageSelected = value; }
		}
		public string ImageSelectedOver
		{
			get { return this.imageSelectedOver; }
			set { this.imageSelectedOver = value; }
		}
		public bool IsDivider
		{
			get { return this.isDivider; }
			set { this.isDivider = value; }
		}
		public int Width
		{
			get { return this.width; }
			set { this.width = value; }
		}
		public int Height
		{
			get { return this.height; }
			set { this.height = value; }
		}
		public int RightIconWidth
		{
			get { return this.rightIconWidth; }
			set { this.rightIconWidth = value; }
		}
        public int RightIconHeight
		{
			get { return this.rightIconHeight; }
			set { this.rightIconHeight = value; }
		}
		public string RightIconAltText
		{
			get { return this.rightIconAltText; }
			set { this.rightIconAltText = value; }
		}
		public string LeftIconAltText
		{
			get { return this.leftIconAltText; }
			set { this.leftIconAltText = value; }
		}
		public string OnClickClientCode
		{
			get { return this.onClickClientCode; }
			set { this.onClickClientCode = value; }
		}
		public int LeftIconWidth
		{
			get { return this.leftIconWidth; }
			set { this.leftIconWidth = value; }
		}
		public int LeftIconHeight
		{
			get { return this.leftIconHeight; }
			set { this.leftIconHeight = value; }
		}
		public int ImageWidth
		{
			get { return this.imageWidth; }
			set { this.imageWidth = value; }
		}
		public int ImageHeight
		{
			get { return this.imageHeight; }
			set { this.imageHeight = value; }
		}
		public bool Selected
		{
			get { return this.selected; }
			set { this.selected = value; }
		}
		public bool Enabled
		{
			get { return this.enabled; }
			set { this.enabled = value; }
		}
		public bool Visible
		{
			get { return this.visible; }
			set { this.visible = value; }
		}
		#endregion
	}
}
